-- 引入 TweenService
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local function SetTrailIsEnalble(model,isOpen)
    for _,v in pairs(model:GetDescendants()) do
        if v:IsA("Trail") then
            v.Enabled=isOpen
        end
    end
end

-- 创建发射箭的函数
local function tween_shoot(startPos, endPos, arrowModel, speed)

    SetTrailIsEnalble(arrowModel,false)

    -- 计算方向
    local dir = (endPos - startPos).unit
    local arrowCFrame= CFrame.new(startPos,startPos+dir)
    local CFValue=Instance.new("CFrameValue",arrowModel)
    CFValue.Value=arrowCFrame

    CFValue.Changed:Connect(function(value)
        arrowModel:SetPrimaryPartCFrame(CFValue.Value)

    end)

    -- 设置箭的初始位置和方向
    arrowModel:SetPrimaryPartCFrame(arrowCFrame)



    -- 计算飞行时间
    local distance = (endPos - startPos).magnitude

    local flightTime = distance / speed

    -- 创建Tween信息
    local tweenInfo = TweenInfo.new(
        flightTime,                -- 时间
        Enum.EasingStyle.Linear    -- 线性过渡
    )

    -- 创建目标属性
    local goal = {}
    goal.Value = CFrame.new(endPos,endPos+dir)

    -- 创建Tween
    local tween = TweenService:Create(CFValue, tweenInfo, goal)


    local arrive=_G.CommonOHOH.load.Connect().new()

    local obj={
        flytime=flightTime,--子弹到达目的的时间
        direction=dir,
        arriveEvent=arrive,
        dtorEvent=_G.CommonOHOH.load.Connect().new(),
        cfValue=CFValue,
        model=arrowModel,
        dtor=function(this)
            this:clearFly()
            this.dtorEvent:Action()
            this.cfValue:Destroy()
            this.arriveEvent:dtor()
            this.dtorEvent:dtor()
            this.direction=nil
            this.cfValue=nil
            this.model=nil
            this.dtorEvent=nil
            this.arriveEvent=nil
            this.dtor=nil
            this.clearFly=nil
            this.addFlyCon=nil
        end,
        
        addFlyCon=function(this,con)
            this.fly=con
        end,

        clearFly=function(this)
            if this.fly then
                SetTrailIsEnalble(this.model,false)
                this.fly:Destroy()
                this.fly=nil
            end
        end
    }

    obj:addFlyCon(tween)


     tween.Completed:Connect(function()
        obj:clearFly()
        if obj and  obj.arriveEvent then
            local list=obj.arriveEvent:Action()
            local t=0
            for _,v in pairs(list) do
                t=t+v
            end
            if t>0 then
                task.wait(t)
                obj:dtor()
            else
                obj:dtor()
            end
        end
    end)

            --开启拖尾
    SetTrailIsEnalble(arrowModel,true)
    -- 播放Tween
    tween:Play()

    return obj

end

-- 创建发射箭的函数
local function stepped_upd_Shoot( startPos, endPos, arrowModel, speed)

    SetTrailIsEnalble(arrowModel,false)

    -- 计算方向
    local dir = (endPos - startPos).unit

    -- 设置箭的初始位置和方向
    local arrowCFrame = CFrame.new(startPos,startPos+dir)
    arrowModel:SetPrimaryPartCFrame(arrowCFrame)

    -- 计算飞行时间
    local distance = (endPos - startPos).magnitude
    local flightTime = distance / speed
    local startTime = tick()

    -- 更新箭的位置
    local function updateArrow(deltaTime)
        
        local currentTime = tick()
        local elapsedTime = currentTime - startTime

        -- 检查是否达到飞行时间
        if elapsedTime >= flightTime then
            return false -- 停止更新
        end

        local progress = elapsedTime / flightTime
        local newPos = startPos + dir * (distance * progress)
        local nextCFrame=CFrame.new(newPos, newPos + dir)

        arrowModel:SetPrimaryPartCFrame(nextCFrame)
        return true -- 继续更新
    end

    local arrive=_G.CommonOHOH.load.Connect().new()

    
    local obj={
        flytime=flightTime,--子弹到达目的的时间
        direction=dir,
        arriveEvent=arrive,
        dtorEvent=_G.CommonOHOH.load.Connect().new(),
        model=arrowModel,
        dtor=function(this)
            this:clearFly()
            this.dtorEvent:Action()
            this.arriveEvent:dtor()
            this.dtorEvent:dtor()
            this.direction=nil
            this.model=nil
            this.dtorEvent=nil
            this.arriveEvent=nil
            this.dtor=nil
            this.clearFly=nil
            this.addFlyCon=nil

        end,

        addFlyCon=function(this,con)
            this.fly=con
        end,

        clearFly=function(this)
            if this.fly then
                SetTrailIsEnalble(this.model,false)
                this.fly:Disconnect()
                this.fly=nil
            end
        end
    }

    SetTrailIsEnalble(arrowModel,true)

    -- 连接到RunService的RenderStepped事件
    local steppCon = RunService.Stepped:Connect(function(deltaTime)
        if not updateArrow(deltaTime) then
            obj:clearFly()

            if obj and  obj.arriveEvent then
                local list=obj.arriveEvent:Action()
                local t=0
                for _,v in pairs(list) do
                    t=t+v
                end
                if t>0 then
                    task.wait(t)
                    obj:dtor()
                else
                    obj:dtor()
                end
            end
        end
    end)
    obj:addFlyCon(steppCon)
    return obj
end
-------------------------------------------------------------

local M = _G.CommonOHOH.class.new(script);

--必须注意：移动时 不能进行碰撞检测
function M.TweenShoot(startPos, endPos, arrowModel, speed)
    return tween_shoot(startPos, endPos, arrowModel, speed)
end;

function M.UpdateShoot(startPos, endPos, arrowModel, speed)
    return stepped_upd_Shoot(startPos, endPos, arrowModel, speed)
end;

function M.Shoot(startPos, endPos, arrowModel, speed)
    return  M.TweenShoot(startPos, endPos, arrowModel, speed)
end
return M
